/*
* MIT License
*
* Copyright (c) 2017 wen.gu <454727014@qq.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/***************************************************************************
* Name: vos_log.c
*
* Purpose: virtual os virtual log interface define
*
* Developer:
*   wen.gu , 2018-08-08
*
* TODO:
*
***************************************************************************/
#include <stdio.h>

#include "vos_log.h"
#include "vos_sys.h"

/***************************************************************************
*
* macro define
*
***************************************************************************/

/***************************************************************************
*
* data structure define
*
***************************************************************************/


static vosLogCallbackFunc_t gLogCallback = NULL;
static eVosLogLevel gLogLevel = VL_LevelDebug;
static const char* gLogModuleName = NULL;
static GBOL gLogEnableTimestamp = GFALSE;
/***************************************************************************
*
* inner API define
*
***************************************************************************/

static void makeTimestampStr(char buf[], size_t len)
{
    vosDate_t vd;
    vosSysDateTime(&vd);

    snprintf(buf, len, "%d:%02d:%02d:%02d:%02d:%02d",
        vd.year, vd.mon, vd.day, vd.hour, vd.min, vd.sec);

}

static void makeLogPrefix(char buf[], size_t len, /** output buffer */
                          eVosLogLevel vll, const char* tag,
                          const char* func, int line, const char* type)
{
    char timestampBuf[128] = { 0 };
    /** process format param */

    if (gLogEnableTimestamp == GTRUE)
    {
        makeTimestampStr(timestampBuf, sizeof(timestampBuf) - 1);
    }
    

    snprintf(buf, len, "%s[%s][%s][%s.%d][%s]:",
        timestampBuf, gLogModuleName ? gLogModuleName : "VOS",
        tag, func, line, type);
}


static void defaultLogPrint(eVosLogLevel vll, const char* prefix, const char* str)
{
    if (prefix && str)
    {
        printf("%s%s", prefix, str);
    }
}

/***************************************************************************
*
* API define
*
***************************************************************************/
void vosLogPrint(eVosLogLevel vll, const char* tag,
                 const char* func, int line, const char* type,
                 const char* fmt, ...)
{
    if (vll <= gLogLevel)
    {
        if (fmt)
        {
            char prefixBuf[512] = { 0 };

            char* tempBuf = (char*)malloc(4096);
            va_list args;
            va_start(args, fmt);

            /** process args */

            vsnprintf(tempBuf, 4096 - 1, fmt, args);
            va_end(args);

            makeLogPrefix(prefixBuf, 511, vll, tag, func, line, type);



            if (gLogCallback)
            {
                gLogCallback(vll, prefixBuf, tempBuf);
            }
            else
            {
                defaultLogPrint(vll, prefixBuf, tempBuf);
            }

            free(tempBuf);
        }
    }
}


void vosLogSetLevel(eVosLogLevel vll)
{
    gLogLevel = vll;
}

void vosLogSetModuleName(const char* name)
{
    gLogModuleName = name;
}

void vosLogSetPrintCallback(vosLogCallbackFunc_t cb)
{
    gLogCallback = cb;
}


void vosLogEnableTimestamp(GBOL enable)
{
    gLogEnableTimestamp = enable;
}


eVosLogLevel vosLogGetLevel()
{
    return gLogLevel;
}

const char*  vosLogGetModuleName()
{
    return gLogModuleName ? gLogModuleName : "VOS";
}